package org.geekbang.prepare.lesson2.jndi;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;

/**
 * JNDI database connection.
 * <br> @author leo
 * <br> @date 2021/6/19
 * <br> @since 1.0.0
 */
@WebServlet("/jndi/connect")
public class JndiConnectDataSourceServlet extends HttpServlet {

    private DataSource dataSource;

    private final Object MUTEX = new Object();

    private final static String ENV_JNDI_URI = "java:/comp/env";

    private final static String DB_JNDI_URI = "jdbc/MyDB";

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        try (Connection connection = getConnection();
             PrintWriter printWriter = resp.getWriter()){
            if (connection != null) {
                printWriter.println("The connection is successful");
                return;
            }
            printWriter.println("The connection fails");
        } catch (SQLException e) {
            throw  new ServletException(e);
        }
    }

    @Override
    public void init() throws ServletException {
        loadDatabase();
    }

    private void loadDatabase() throws ServletException {
        if (dataSource == null) {
            synchronized (MUTEX) {
                if (dataSource == null) {
                    try {
                        Context context = new InitialContext();
                        Context envContext = (Context) context.lookup(ENV_JNDI_URI);
                        dataSource = (DataSource) envContext.lookup(DB_JNDI_URI);
                    } catch (NamingException e) {
                        throw new ServletException(e);
                    }
                }
            }
        }
    }

    private Connection getConnection() throws ServletException {
        try {
            if (dataSource != null) {
                return dataSource.getConnection();
            }
            System.out.println("datasource is null!");
            loadDatabase();
            return dataSource.getConnection();
        } catch (SQLException e) {
            log("获取connection 异常",e);
        }
        return null;
    }

    @Override
    public void destroy() {
        log("servlet is destroy !");
    }
}
